package org.loong.crypto.service.software.provider.asymmetric.ecdsa;

import java.security.interfaces.ECPrivateKey;

import org.loong.crypto.common.exception.CryptoException;
import org.loong.crypto.common.exception.InvalidKeyException;
import org.loong.crypto.core.algorithm.SignatureAlgorithm;
import org.loong.crypto.core.utils.ECKeyUtils;
import org.loong.crypto.service.core.provider.Signer;
import org.loong.crypto.service.core.provider.impl.ECDSAProvider;

import cn.hutool.crypto.asymmetric.Sign;

/**
 * ECDSA signer of data.
 */
public class ECDSASigner extends ECDSAProvider implements Signer {

    /**
     * The private key.
     */
    private ECPrivateKey privateKey;

    /**
     * Creates a new signer.
     *
     * @param keyBytes the private key bytes. Must not be {@code null}.
     */
    public ECDSASigner(final byte[] keyBytes) {
        this(ECKeyUtils.toECPrivateKey(keyBytes));
    }

    /**
     * Creates a new signer.
     *
     * @param privateKey the private key. Must not be {@code null}.
     */
    public ECDSASigner(final ECPrivateKey privateKey) {
        if (privateKey == null) {
            throw new InvalidKeyException("The private ECDSA key must not be null.");
        }

        if (!"EC".equalsIgnoreCase(privateKey.getAlgorithm())) {
            throw new InvalidKeyException("The private key algorithm must be ECDSA.");
        }

        this.privateKey = privateKey;
    }

    @Override
    public byte[] sign(final SignatureAlgorithm algorithm, final byte[] data) throws CryptoException {
        try {
            Sign signature = new Sign(algorithm.getName(), privateKey, null);
            return signature.sign(data);
        } catch (cn.hutool.crypto.CryptoException e) {
            throw new CryptoException("ECDSA signature exception: " + e.getMessage(), e);
        }
    }
}
